package com.fenquen.sourceguard.dencrypt;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class Dencrypt {

    static {
        String libFileName = "libsourceguard.so";
        String suffix = ".so";

        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("windows")) {
            libFileName = "libsourceguard.dll";
            suffix = ".dll";
        } else if (osName.contains("darwin")) {
            libFileName = "libsourceguard.dylib";
            suffix = ".dylib";
        }

        try (InputStream inputStream = Dencrypt.class.getClassLoader().getResourceAsStream(libFileName)) {
            if (null == inputStream) {
                throw new FileNotFoundException(libFileName);
            }

            File temp = File.createTempFile("libjfsnotify", suffix);
            temp.deleteOnExit();
            Files.copy(inputStream, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);

            System.load(temp.getAbsolutePath());
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    public static byte[] decrypt(byte[] byteArr) {
        if (needDecrypt(byteArr)) {
            return decrypt0(byteArr);
        }

        return byteArr;
    }

    private static native byte[] decrypt0(byte[] encryptedBytes);

    public static byte[] encrypt(byte[] originByteArr, boolean bindMachine) {
        return encrypt0(originByteArr, bindMachine);
    }

    private static native byte[] encrypt0(byte[] originBytes, boolean bindMachine);

    private static boolean needDecrypt(byte[] byteArr) {
        return byteArr[0] == 0x01 &&
                (byteArr[1] == 0x00 || byteArr[1] == (byte) 0xdd) &&
                byteArr[2] == 0x01 &&
                byteArr[3] == 0x00;
    }

}
